package bb.lanxing.lib.devices.ble.device;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;

import java.util.UUID;

import bb.lanxing.lib.devices.api.SmartDevice;
import bb.lanxing.lib.devices.cad01.Cadence01Controller;
import bb.lanxing.lib.devices.core.ble.SpecificationAttributes;
import bb.lanxing.lib.devices.core.dfu.ICDMDfuDevice;
import bb.lanxing.lib.devices.core.dfu.IDfuAdapter;
import bb.lanxing.lib.devices.core.dfu.IDfuDevice;
import bb.lanxing.lib.devices.sprint.Commands;
import bb.lanxing.lib.devices.sprint.Response;
import bb.lanxing.lib.devices.sprint.SimpleBleDeviceDfuAdapter;
import bb.lanxing.util.Log;
import gov.nist.core.Separators;

public class Cadence01Device extends StandardCadenceDevice implements Cadence01Controller, IDfuDevice, ICDMDfuDevice {
    private static final int CSC_FLAG_CADENCE = 2;
    private static final int CSC_FLAG_SPEED = 1;
    private BluetoothGattCharacteristic cmdNotifyService;
    private BluetoothGattCharacteristic cmdService;
    private boolean isSwitching;
    private IDfuAdapter mDfuAdapter;

    private static final UUID BLE_SWITCH_CADENCE_SERVICE = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
    private static final UUID BLE_SWITCH_CADENCE_CMD = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
    private static final UUID BLE_SWITCH_CADENCE_CMD_NOTIFY = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");

    public Cadence01Device(SmartDevice smartDevice) {
        super(smartDevice);
        this.isSwitching = false;
    }

    public Cadence01Device(Context context, SmartDevice smartDevice) {
        super(smartDevice);
        this.isSwitching = false;
        init(context, smartDevice.getAddress(), new Cadence01GattCallback(this));
    }

    public Cadence01Device(Context context, SmartDevice smartDevice, BluetoothGattCallback bluetoothGattCallback) {
        super(smartDevice);
        this.isSwitching = false;
        init(context, smartDevice.getAddress(), bluetoothGattCallback);
    }

    @Override
    public void onServicesDiscovered() {
        super.onServicesDiscovered();
        readFirmwareVersion();
        //writeDeviceName();
        readManufacturer();
        readModel();
        BluetoothGattService service = this.mBluetoothGatt.getService(BLE_SWITCH_CADENCE_SERVICE);
        this.cmdService = service.getCharacteristic(BLE_SWITCH_CADENCE_CMD);
        BluetoothGattCharacteristic characteristic = service.getCharacteristic(BLE_SWITCH_CADENCE_CMD_NOTIFY);
        this.cmdNotifyService = characteristic;
        if (characteristic != null) {
            setCharacteristicNotification(characteristic, true);
        }
        IDfuAdapter iDfuAdapter = this.mDfuAdapter;
        if (iDfuAdapter != null) {
            iDfuAdapter.release();
            this.mDfuAdapter = null;
        }
        initBatteryNotify();
    }

    private void initBatteryNotify() {
        BluetoothGattService service = this.mBluetoothGatt.getService(BLE_BATTERY_SERVICE);
        if (service != null) {
            setCharacteristicNotification(service.getCharacteristic(BLE_BATTERY_CHARACTERISTIC), true);
        }
    }

    @SuppressLint("MissingPermission")
    @Override
    public boolean switchTo(int mode) {
        if (this.cmdService == null || getBluetoothGatt() == null) {
            return false;
        }
//        byte[] bytes = Commands.create(48, new byte[]{(byte) mode}).toBytes();
        byte[] bytes = new byte[4];
        if (mode == 0) {
            bytes[0] = 5;
        } else {
            bytes[0] = 4;
        }
        bytes[2] = 10;
        bytes[3] = 10;

        this.cmdService.setValue(bytes);
        d("Writing characteristic " + this.cmdService.getUuid() + " (" + bytes + Separators.RPAREN);
        String sb = "gatt.writeCharacteristic(" + this.cmdService.getUuid() + Separators.RPAREN;
        d(sb);
        this.isSwitching = getBluetoothGatt().writeCharacteristic(this.cmdService);

        if (isSwitching) {
            disconnect();
        }
        Log.d("SwitchableCadenceSpeedDevice", "switchTo isSwitching=" + isSwitching);
        return this.isSwitching;
    }

    @Override
    public IDfuAdapter getDfuAdapter() {
        if (this.mDfuAdapter == null) {
            this.mDfuAdapter = new SimpleBleDeviceDfuAdapter(this.mAppContext, this);
        }
        return this.mDfuAdapter;
    }

    @Override
    public boolean shouldAutoConnection() {
        return this.mDfuAdapter != null && !this.isSwitching;
    }

    @Override
    public BluetoothGattCharacteristic getCDMService() {
        return this.cmdService;
    }


    public static class Cadence01GattCallback extends CadenceGattCallback {
        @Override
        public void onCharacteristicRead(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic, int i) {
            super.onCharacteristicRead(bluetoothGatt, bluetoothGattCharacteristic, i);
        }

        public Cadence01GattCallback(StandardCadenceDevice standardCadenceDevice) {
            super(standardCadenceDevice);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic) {
            super.onCharacteristicChanged(bluetoothGatt, bluetoothGattCharacteristic);
            UUID uuid = bluetoothGattCharacteristic.getUuid();
            byte[] value = bluetoothGattCharacteristic.getValue();
            if (uuid.equals(Cadence01Device.BLE_SWITCH_CADENCE_CMD_NOTIFY)) {
                Response createResponse = Commands.createResponse(value);
                if (createResponse.getCmd() != 0) {
                    createResponse.getCmd();
                }
                this.mClientRef.d("Response: " + createResponse);
            } else if (SpecificationAttributes.BLE_BATTERY_CHARACTERISTIC.equals(uuid)) {
                onReadBattery(bluetoothGattCharacteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0));
            }
        }
    }
}
